<!-- 新闻推荐页面 -->

<script setup lang="ts">
import { TabPaneName } from 'element-plus';
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import type { PlainNews } from '@/types/news'
import service from '@/utils/axios';
import { ApiResponse, stringToApiResponse } from '@/types/apiResponse';
import { onUnmounted } from 'vue';

const router = useRouter()

const avtiveTab = ref('0')

// 新闻分类全局变量
const sortId = ref(0)

// 从后端获取新闻分类
const newsSorts = ref([
  { id: 1, label: '科技' },
  { id: 2, label: '财经' },
  { id: 3, label: '军事' }
])

// 加载新闻分类接口
const loadNewsSorts = async () => {
  const response = await service.get<string>('/news/getSorts')

  return stringToApiResponse(response.data); 
}

// 新闻列表数据
const newsList = ref<PlainNews[]>([
  {
    id: 0,
    title: '',
    summary: '',
    author: '科技日报',
    likes: 0,
    favorites: 0,
    time: '',
    image: '',
    tags: []
  }
  // ... 其他新闻数据
])

// 初始加载的数目。注意此值一定要是每次加载加载数目的整数倍，否则会导致新闻加载重复或缺失
const initialLoadNum = ref(8)
// 每次调用加载时，加载的数目。类似于分页器中的分页大小，但该值是固定的
const pageSize = ref(4)
// 第一次调用“加载更多”功能的方法时，请求的分页页码。每次调用方法时令该值加一
const page = ref(initialLoadNum.value / pageSize.value + 1)
// 是否还有更多数据可加载
const loadHasMore = ref(true)

const loading = ref(false)

// 跳转到详情页
const goToDetail = (id: number) => {
  router.push(`/newsArticle/${id}`)
}

// 加载新闻推荐功能接口
const loadRecommendNews = async (sortId: number, page: number, pageSize: number): Promise<ApiResponse<string>> => {

  const response = await service.get<string>('/news/getRecommends', {
    params: {
      newsSort: sortId, 
      page: page, 
      pageSize: pageSize
    }
  })

  return stringToApiResponse(response.data); 
}

// 加载新闻推荐
const load = async () => {
  if (loading.value || !loadHasMore.value) return;

  loading.value = true;

  await new Promise((resolve) => setTimeout(resolve, 200));

  const recommendResponse = await loadRecommendNews(sortId.value, page.value, pageSize.value);
  if (recommendResponse.code === 200) {
    const data = JSON.parse(JSON.stringify(recommendResponse.data));
    
    newsList.value.push(...data.plainNewsInfoList);

    // 每次触发currentPage + 1 currentPage.value += 1;
    page.value += 1;
    
    if(newsList.value.length < pageSize.value) {
      // 若记录数小于pageSize.value，说明后端没有更多数据，则设置loadHasMore为false
      loadHasMore.value = false;
    }
  } else {
    loadHasMore.value = false;
  }
  loading.value = false;

}

// 加载更多
const loadMore = async () => {
  if (!loadHasMore.value) return;

  // 可使用concat拼接数据
  const scrollTop = document.documentElement.scrollTop;
  const clientHeight = document.documentElement.clientHeight;
  const scrollHeight = document.documentElement.scrollHeight;
  if (scrollHeight - scrollTop - clientHeight < 50) {
    load();
  }
}

// 初始加载
onMounted(async () => {
  window.scrollTo(0, 0); // 页面加载完成后滚动到顶部

  window.addEventListener('scroll', loadMore)

  // 加载新闻分类
  const sortResponse = await loadNewsSorts();
  if (sortResponse.code === 200) {
    const data = JSON.parse(JSON.stringify(sortResponse.data));
    
    newsSorts.value = data.newsSorts;
  }

  // 初始加载推荐，分页页码为1，分页大小为初始加载数
  const recommendResponse = await loadRecommendNews(sortId.value, 1, initialLoadNum.value);
  if (recommendResponse.code === 200) {
    const data = JSON.parse(JSON.stringify(recommendResponse.data));
    
    newsList.value = data.plainNewsInfoList;
    
    if(newsList.value.length < initialLoadNum.value) {
      // 若记录数小于initialLoadNum.value，说明后端没有更多数据，则设置loadHasMore为false
      loadHasMore.value = false;
    }
  }
})

onUnmounted(() => {
  window.removeEventListener('scroll', loadMore)
})

// 切换分类标签，获取对应分类的新闻推荐
const getRecommendNews = async (name: TabPaneName) => {
  // 每次切换分类标签时，重置加载状态
  loadHasMore.value = true;
  page.value = initialLoadNum.value / pageSize.value + 1;

  sortId.value = Number(name)

  const recommendResponse = await loadRecommendNews(sortId.value, 1, initialLoadNum.value);
  if (recommendResponse.code === 200) {
    const data = JSON.parse(JSON.stringify(recommendResponse.data));
    
    newsList.value = data.plainNewsInfoList;
    
    if(newsList.value.length < initialLoadNum.value) {
      // 若记录数小于initialLoadNum.value，说明后端没有更多数据，则设置loadHasMore为false
      loadHasMore.value = false;
    }
  } else {
    // 若没有对应分类的新闻，则清空列表
    newsList.value = [];
  }
}
</script>

<template>
  <div class="space-y-4">
    <!-- 分类标签 -->
    <div class="bg-white rounded-lg px-4">
      <el-tabs v-model="avtiveTab" @tab-change="getRecommendNews">
        <el-tab-pane label="推荐" name="0">
        </el-tab-pane>
        <el-tab-pane v-for="sort in newsSorts" :label=sort.label :name=sort.id>
        </el-tab-pane>

      </el-tabs>
    </div>

    <!-- 新闻列表 -->
    <div v-loading="loading">
      <div v-if="newsList.length === 0">
        <el-empty description="暂无内容" />
      </div>
      <ElCard v-for="article in newsList" :key="article.id" class="hover:shadow-lg transition-all cursor-pointer mb-4"
        @click="goToDetail(article.id)">
        <div class="flex gap-6">
          <div class="flex-1 ml-4">
            <h3 class="text-xl font-bold mt-4 mb-4 hover:text-blue-500 line-clamp-2">
              {{ article.title }}
            </h3>
            <p class="text-gray-600 text-sm line-clamp-1 mb-8">
              {{ article.summary }}
            </p>
            <div class="flex items-center gap-3 text-sm text-gray-500">
              <span class="flex items-center">
                <el-icon class="mr-1">
                  <User />
                </el-icon>
                {{ article.author }}
              </span>
              <span class="flex items-center">
                <i class="fa fa-thumbs-o-up mr-1"></i>
                {{ article.likes }}
              </span>
              <span class="flex items-center">
                <i class="fa fa-star-o mr-1"></i>
                {{ article.favorites }}
              </span>
              <span class="flex items-center">
                <el-icon class="mr-1">
                  <Timer />
                </el-icon>
                {{ article.time }}
              </span>
              <div class="flex gap-2">
                <el-tag v-for="tag in article.tags" :key="tag" size="small" effect="plain">
                  {{ tag }}
                </el-tag>
              </div>
            </div>
          </div>
          <div class="w-[200px] h-[150px] flex-shrink-0">
            <el-image v-if="article.image" :src="article.image" fit="cover" class="w-full h-full rounded" lazy/>
          </div>
        </div>
      </ElCard>
    </div>
    <div v-if="!loadHasMore && newsList.length > 0" class="text-center">
      没有更多数据了
    </div>

    <el-backtop :right="100" :bottom="100" />

  </div>
</template>

<style lang="less" scoped>
.el-card {
  &:hover {
    transform: translateY(-2px);
  }
}
</style>
